
namespace{

    typedef ::std::string
        Str;
    typedef Str::value_type
        Ch;

    Str Deep(const size_t d,const Ch ch=' '){ return Str(d*2,ch); }

    struct Sample: public std::iterator<std::bidirectional_iterator_tag , Sample>
    {
        typedef list<Sample> 
            List;

        typedef IteratorWrapper<List, Way::begin>
            iterator;
        typedef IteratorWrapper<List, Way::cbegin>
            const_iterator;
        typedef IteratorWrapper<List, Way::rbegin>
            reverse_iterator;
        typedef IteratorWrapper<List, Way::crbegin>
            const_reverse_iterator;
       

        Sample(const size_t n, Sample* parent= nullptr)
            :mNum(n)
            ,mList()
            ,mParent(parent)
        {}

        Sample& Add(const size_t n)
        {
            mList.emplace_back(n, this);
            return *this;
        }
        Sample& Open(const size_t n)
        {
            mList.emplace_back(n,this);
            return mList.back();
        }
        Sample& Close()
        {
            if(mParent)
                return *mParent;
            return *this;
        }

        Str GetName()const 
        {
            return "block-" + ::std::to_string(mNum);
        }

        void View()const { View(0); }

        const Sample& View(const size_t d)const
        {
            std::cout<< Deep(d) << "block-"<< mNum <<'\n';
            if(!mList.empty())
                for(const auto& f: mList)
                    f.View(d+1);
            return *this;
        }

        iterator               begin()          { return iterator(mList, mList.begin());                 }
        iterator               end()            { return iterator(mList, mList.end());                   }
        const_iterator         begin()const     { return const_iterator(mList, mList.begin());           }
        const_iterator         end()const       { return const_iterator(mList, mList.end());             }

        const_iterator         cbegin()const    { return const_iterator(mList, mList.cbegin());          }
        const_iterator         cend()const      { return const_iterator(mList, mList.cend());            }

        reverse_iterator       rbegin()         { return reverse_iterator(mList, mList.rbegin());        }
        reverse_iterator       rend()           { return reverse_iterator(mList, mList.rend());          }
        const_reverse_iterator rbegin()const    { return const_reverse_iterator(mList, mList.rbegin());  }
        const_reverse_iterator rend()const      { return const_reverse_iterator(mList, mList.rend());    }

        const_reverse_iterator crbegin()const   { return const_reverse_iterator(mList, mList.crbegin()); }
        const_reverse_iterator crend()const     { return const_reverse_iterator(mList, mList.crend());   }

        size_t  mNum;
        List    mList;
        Sample* mParent;
    };
}//namespace
